﻿using Elements;
using Elements.Links;
using Elements.Shapes;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FlowChartDemo
{
    public partial class FormDemo05V1 : FormBase
    {
        public FormDemo05V1()
        {
            InitializeComponent();
            DemoTitle = "第07节随课Demo  Part1";
            DemoNote = "效果：抽象图形基类，从基类派生出矩形、圆形，实现拖动、连线。";

            SetStyle(ControlStyles.AllPaintingInWmPaint |
                ControlStyles.UserPaint |
                ControlStyles.OptimizedDoubleBuffer,true);
        }
               
        //注：文章中说明要添加Elements的项目引用。
        
        /// <summary>
        /// 形状集合
        /// </summary>
        List<ShapeBase> Shapes = new List<ShapeBase>();
        /// <summary>
        /// 连线集合
        /// </summary>
        List<LinkBase> Links = new List<LinkBase>();

        Bitmap _bmp;

        /// <summary>
        /// 重新绘制当前所有矩形和连线
        /// </summary>
        /// <param name="g"></param>
        void DrawAll(Graphics g1)
        {
            //创建内存绘图，将形状和连线绘制到此内存绘图上，然后再一次性绘制到控件上
            _bmp = new Bitmap(panel1.Width, panel1.Height);
            var g = Graphics.FromImage(_bmp);

            //设置显示质量
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

            g.Clear(panel1.BackColor);

            //绘制所有形状
            foreach (var sp in Shapes)
            {
                sp.Draw(g);
            }

            //绘制所有连线
            foreach (var ln in Links)
            {
                ln.Draw(g);
            }

            //绘制内存绘图到控件上
            g1.DrawImage(_bmp, new PointF(0, 0));
        }

        //注：文章中说明；此处不过于抽象，后续章节会有

        /// <summary>
        /// 当前是否有鼠标按下，且有矩形被选中
        /// </summary>
        bool _isMouseDown = false;
        /// <summary>
        /// 最后一次鼠标的位置
        /// </summary>
        Point _lastMouseLocation = Point.Empty;
        /// <summary>
        /// 当前被鼠标选中的矩形
        /// </summary>
        ShapeBase _selectedShape = null;

        /// <summary>
        /// 添加连线时选中的第一个形状
        /// </summary>
        ShapeBase _selectedStartShape = null;
        /// <summary>
        /// 添加连线时选中的第一个形状
        /// </summary>
        ShapeBase _selectedEndShape = null;
        /// <summary>
        /// 是否正添加连线
        /// </summary>
        bool _isAddLink = false;

        /// <summary>
        /// 获取不同的背景颜色
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        Color GetColor(int i)
        {
            switch (i)
            {
                case 0: return Color.Red;
                case 1: return Color.Green;
                case 2: return Color.Blue;
                case 3: return Color.Orange;
                case 4: return Color.Purple;
                default: return Color.Red;
            }
        }


        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            var rs = new RectShape()
            {
                Id = "矩形" + (Shapes.Count + 1),
                Rect = new Rectangle()
                {
                    X = 50,
                    Y = 50,
                    Width = 100,
                    Height = 100,
                },
                FontColor = Color.White,
                BackgroundColor = GetColor(Shapes.Count),
                Text = "矩形" + (Shapes.Count + 1),
                TextFont = Font,

            };
            Shapes.Add(rs);

            //重绘所有
            DrawAll(panel1.CreateGraphics());
        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            //当鼠标按下时

            //取最上方的形状
            var sp = Shapes.FindLast(a => a.Rect.Contains(e.Location));
           
            if (!_isAddLink)
            {
                //当前没有处理连线状态
                if (sp != null)
                {
                    //设置状态及选中矩形
                    _isMouseDown = true;
                    _lastMouseLocation = e.Location;
                    _selectedShape = sp;
                }
            }
            else
            {
                //正在添加连线

                if (_selectedStartShape == null)
                {
                    //证明没有矩形和圆形被选中则设置开始形状
                    if (sp != null)
                    {
                        //设置开始形状
                        _selectedStartShape = sp;
                    }
                    toolStripStatusLabel1.Text = "请点击第2个形状";
                }
                else
                {
                    //判断第2个形状是否是第1个形状
                    if (sp != null)
                    {
                        //判断当前选中的矩形是否是第1步选中的矩形
                        if (_selectedStartShape.Id == sp.Id)
                        {
                            toolStripStatusLabel1.Text = "不可选择同一个形状，请重新点击第2个形状";
                            return;
                        }
                    }

                    if (sp != null)
                    {
                        //设置结束形状
                        _selectedEndShape = sp;
                    }
                    else
                    {
                        return;
                    }


                    //两个形状都设置了，便添加一条新连线
                    Links.Add(new LineLink()
                    {
                        Id = "连线" + (Links.Count + 1),
                        BackgroundColor=GetColor(Links.Count),
                        StartShape=_selectedStartShape,
                        EndShape=_selectedEndShape,
                    });
                    //两个形状都已选择，结束添加连线状态
                    _isAddLink = false;
                    toolStripStatusLabel1.Text = "";
                    //重绘以显示连线
                    DrawAll(panel1.CreateGraphics());


                }

            }

        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            //当鼠标移动时

            //如果处于添加连线时，则不移动形状
            if (_isAddLink) return;

            if (_isMouseDown)
            {
                //当且仅当：有鼠标按下且有矩形被选中时，才进行后续操作

                //改变选中矩形的位置信息，随着鼠标移动而移动

                //计算鼠标位置变化信息
                var moveX = e.Location.X - _lastMouseLocation.X;
                var moveY = e.Location.Y - _lastMouseLocation.Y;

                //将选中形状的位置进行同样的变化
                var oldXY = _selectedShape.Rect.Location;
                oldXY.Offset(moveX, moveY);
                _selectedShape.Rect = new Rectangle(oldXY, _selectedShape.Rect.Size);

                //记录当前鼠标位置
                _lastMouseLocation.Offset(moveX, moveY);

                //重绘所有矩形
                DrawAll(panel1.CreateGraphics());
            }

        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            //当鼠标松开时
            if (_isMouseDown)
            {
                //当且仅当：有鼠标按下且有矩形被选中时，才进行后续操作

                //重置相关记录信息
                _isMouseDown = false;
                _lastMouseLocation = Point.Empty;
                _selectedShape = null;
            }
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            _isAddLink = true;
            _selectedStartShape = null;
            _selectedEndShape = null;
            toolStripStatusLabel1.Text = "请点击第1个形状";
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            _isAddLink = false;
            _selectedStartShape = null;
            _selectedEndShape = null;
            toolStripStatusLabel1.Text = "";
            DrawAll(panel1.CreateGraphics());
        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            var rs = new EllipseShape()
            {
                Id = "圆形" + (Shapes.Count + 1),
                Rect = new Rectangle()
                {
                    X = 50,
                    Y = 50,
                    Width = 100,
                    Height = 100,
                },
                FontColor = Color.White,
                BackgroundColor = GetColor(Shapes.Count),
                Text = "圆形" + (Shapes.Count + 1),
                TextFont = Font,

            };
            Shapes.Add(rs);

            //重绘所有
            DrawAll(panel1.CreateGraphics());
        }
    }


}
